﻿// (c) Copyright Webber-Cross Software Ltd.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using GalaSoft.MvvmLight;
using WebberCross.Obelisk.MvvmLightDemo.Model;
using System.Collections.Generic;
using System;
using WebberCross.Obelisk.MvvmLightDemo.Navigation;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;

namespace WebberCross.Obelisk.MvvmLightDemo.ViewModel
{
    /// <summary>
    /// This class contains properties that the main View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// You can also use Blend to data bind with the tool's support.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class MainViewModel : TombstonePersistentBase
    {
        private string _notes;
        private List<Person> _people;
        private Person _person;

        // Navigation
        private ICommand _navCommand = null;
        private INavigationService _navService = null;
        private MessageSender<ExampleInitMessage> _sender = null;

        public ICommand NavCommand
        {
          get { return this._navCommand; }
        }

        public string ApplicationTitle
        {
            get { return "OBELISK MVVM LIGHT"; }
        }

        public string PageName
        {
            get { return "Demo page"; }
        }

        /// <summary>
        /// This attribute tells the TombstoneHelper to store this property on dehydration
        /// Because this is a complex type, it must be registered when attaching the TombstoneHelper
        /// An array is used to marshal the List object as it's easier to deserialise
        /// </summary>
        [Persist(PersistMode.Both)]
        public Person[] PeopleArray
        {
            get 
            { 
                if(this._people != null)
                    return this._people.ToArray();

                return null;
            }
            set 
            { 
                if(value != null)
                    this._people = new List<Person>(value); 
            }
        }

        public List<Person> People
        {
            get { return this._people; }
            set { this._people = value; }
        }

        /// <summary>
        /// This attribute tells the TombstoneHelper to store this property on dehydration
        /// Because this is a complex type, it must be registered when attaching the TombstoneHelper
        /// </summary>
        [Persist(PersistMode.Both)]
        public Person Person
        {
            get { return this._person; }
            set 
            {
                if (this._person != value)
                {
                    this._person = value;
                    base.RaisePropertyChanged("Person");
                }
            }
        }

        /// <summary>
        /// This attribute tells the TombstoneHelper to store this property on dehydration
        /// </summary>
        [Persist(PersistMode.TombstonedOnly)]
        public string Notes
        {
            get { return this._notes; }
            set { this._notes = value; }
        }

        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel(INavigationService navService)
        {
            if (IsInDesignMode)
            {
                // Code runs in Blend --> create design time data.
            }
            else
            {
                // Code runs "for real"
              this._navService = navService;
              this._navCommand = new RelayCommand(() =>
                {
                  this.Navigate();
                });
            }
        }

        private void Navigate()
        {
          // Send message to destination VM
          if (this._sender == null)
            this._sender = new MessageSender<ExampleInitMessage>();

          this._sender.SendMessage(new ExampleInitMessage("Hello from MainViewModel"));

          // Navigate
#if WINDOWS8
          this._navService.NavigateTo(ViewModelLocator.EXAMPLE_PAGE_TYPE);
#else
            this._navService.NavigateTo(new Uri("/View/ExampleView.xaml", UriKind.Relative));
#endif
        }

        #region Obelisk methods

        /// <summary>
        /// Occurs after a class has been instantiated for the first time
        /// </summary>
        public override void OnLaunched()
        {
            // Typically data might be loaded from a service, but this is an example
            this._people = new List<Person>();
            this._people.Add(new Person() { Name = "Person A", Birthday = new DateTime(1, 1, 1) });
            this._people.Add(new Person() { Name = "Person B", Birthday = new DateTime(2, 2, 2) });
            this._people.Add(new Person() { Name = "Person C", Birthday = new DateTime(3, 3, 3) });
            this._people.Add(new Person() { Name = "Person D", Birthday = new DateTime(4, 4, 4) });
            this._people.Add(new Person() { Name = "Person E", Birthday = new DateTime(5, 5, 5) });
            this._people.Add(new Person() { Name = "Person R", Birthday = new DateTime(6, 6, 6) });
        }

        /// <summary>
        /// Occurs after an instance has been rehydrated after an activation
        /// </summary>
        public override void OnActivated(bool preserved)
        {

        }

        /// <summary>
        /// Occurs before an instance is dehydrated the tombstoned
        /// </summary>
        public override void OnDeactivated()
        {

        }

        /// <summary>
        /// Occurs when the application is closing
        /// </summary>
        public override void OnClosing()
        {

        }

        #endregion


        // This can be removed because Obelisk offers OnClosing method which does the same

        ////public override void Cleanup()
        ////{
        ////    // Clean up if needed

        ////    base.Cleanup();
        ////}
    }
}